package com.sunwayworld.basemodule.business.prefolder.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.sunwayworld.basemodule.business.batch.bean.LimsBatchSampleProductBean;
import com.sunwayworld.basemodule.business.batch.service.LimsBatchSampleProductService;
import com.sunwayworld.basemodule.business.folder.bean.LimsFolderBean;
import com.sunwayworld.basemodule.business.folder.bean.LimsOrderBean;
import com.sunwayworld.basemodule.business.folder.bean.LimsPreOrderTaskBean;
import com.sunwayworld.basemodule.business.folder.service.LimsFolderService;
import com.sunwayworld.basemodule.business.folder.service.LimsOrderService;
import com.sunwayworld.basemodule.business.folder.service.LimsPreOrderTaskService;
import com.sunwayworld.basemodule.business.operationbatch.bean.LimsOperationBatchBean;
import com.sunwayworld.basemodule.business.operationbatch.bean.LimsOrderTaskSupplementBean;
import com.sunwayworld.basemodule.business.operationbatch.bean.LimsPreTaskSupplementBean;
import com.sunwayworld.basemodule.business.operationbatch.service.LimsOperationBatchService;
import com.sunwayworld.basemodule.business.operationbatch.service.LimsOrderTaskSupplementService;
import com.sunwayworld.basemodule.business.operationbatch.service.LimsPreTaskSupplementService;
import com.sunwayworld.basemodule.business.ordertask.bean.LimsOrderTaskBean;
import com.sunwayworld.basemodule.business.ordertask.service.LimsOrderTaskService;
import com.sunwayworld.basemodule.business.prefolder.bean.LimsPreFolderBean;
import com.sunwayworld.basemodule.business.prefolder.dao.LimsPreFolderDao;
import com.sunwayworld.basemodule.business.prefolder.service.LimsPreFolderService;
import com.sunwayworld.basemodule.common.auditrecord.service.LimsAuditRecordService;
import com.sunwayworld.basemodule.coredata.experimentaltemplate.bean.LimsExperimentalTemplateBean;
import com.sunwayworld.basemodule.coredata.experimentaltemplate.bean.LimsExperimentalTemplateTestBean;
import com.sunwayworld.basemodule.coredata.experimentaltemplate.service.LimsExperimentalTemplateService;
import com.sunwayworld.basemodule.coredata.experimentaltemplate.service.LimsExperimentalTemplateTestMethodService;
import com.sunwayworld.basemodule.coredata.experimentaltemplate.service.LimsExperimentalTemplateTestService;
import com.sunwayworld.basemodule.coredata.product.bean.LimsProductBean;
import com.sunwayworld.basemodule.coredata.product.service.LimsProductService;
import com.sunwayworld.basemodule.coredata.test.bean.LimsTestSupplementBean;
import com.sunwayworld.basemodule.coredata.test.service.LimsTestSupplementService;
import com.sunwayworld.basemodule.samplemanage.sample.bean.LimsSampleBean;
import com.sunwayworld.basemodule.samplemanage.sample.bean.LimsSampleDerivativeBean;
import com.sunwayworld.basemodule.samplemanage.sample.service.LimsSampleDerivativeService;
import com.sunwayworld.basemodule.samplemanage.sample.service.LimsSampleService;
import com.sunwayworld.framework.at.annotation.AuditTrailEntry;
import com.sunwayworld.framework.at.annotation.AuditTrailType;
import com.sunwayworld.framework.constant.Constant;
import com.sunwayworld.framework.context.ApplicationContextHelper;
import com.sunwayworld.framework.context.concurrent.GikamConcurrentLocker;
import com.sunwayworld.framework.data.page.Page;
import com.sunwayworld.framework.data.page.Pagination;
import com.sunwayworld.framework.exception.InvalidDataException;
import com.sunwayworld.framework.i18n.I18nHelper;
import com.sunwayworld.framework.mybatis.mapper.MapperParameter;
import com.sunwayworld.framework.mybatis.mapper.MatchPattern;
import com.sunwayworld.framework.mybatis.mapper.SearchFilter;
import com.sunwayworld.framework.mybatis.page.PageRowBounds;
import com.sunwayworld.framework.restful.data.RestJsonWrapperBean;
import com.sunwayworld.framework.spring.annotation.GikamBean;
import com.sunwayworld.framework.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.thymeleaf.util.ListUtils;

import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

@Repository
@GikamBean
public class LimsPreFolderServiceImpl implements LimsPreFolderService {

    @Autowired
    private LimsPreFolderDao limsPreFolderDao;

    @Lazy
    @Autowired
    private LimsSampleService sampleService;
    @Autowired
    @Lazy
    private LimsSampleDerivativeService limsSampleDerivativeService;

    @Lazy
    @Autowired
    private LimsBatchSampleProductService sampleProductService;

    @Lazy
    @Autowired
    private LimsProductService productService;

    @Lazy
    @Autowired
    private LimsFolderService folderService;

    @Lazy
    @Autowired
    private LimsPreOrderTaskService preOrderTaskService;

    @Lazy
    @Autowired
    private LimsOrderService orderService;

    @Lazy
    @Autowired
    private LimsOrderTaskService orderTaskService;

    @Lazy
    @Autowired
    private LimsExperimentalTemplateTestService etTestService;

    @Lazy
    @Autowired
    private LimsExperimentalTemplateTestMethodService spMethodService;

    @Lazy
    @Autowired
    private LimsAuditRecordService auditRecordService;

    @Lazy
    @Autowired
    private LimsPreTaskSupplementService preTaskSupplementService;

    @Autowired
    private LimsTestSupplementService testSupplementService;

    @Lazy
    @Autowired
    private LimsOperationBatchService operationBatchService;

    @Autowired
    private LimsOrderTaskSupplementService orderTaskSupplementService;
    @Autowired
    private LimsBatchSampleProductService limsBatchSampleProductService;
    @Autowired
    private LimsSampleService limsSampleService;

    @Autowired
    @Lazy
    private LimsExperimentalTemplateService limsExperimentalTemplateService;

    @Override
    @SuppressWarnings("unchecked")
    public LimsPreFolderDao getDao() {
        return limsPreFolderDao;
    }

    @Override
    @Transactional
    @AuditTrailEntry(AuditTrailType.INSERT)
    public Long insert(RestJsonWrapperBean jsonWrapper) {
        LimsPreFolderBean limsPreFolder = jsonWrapper.parseUnique(LimsPreFolderBean.class);
        limsPreFolder.setId(ApplicationContextHelper.getNextIdentity());
        getDao().insert(limsPreFolder);
        return limsPreFolder.getId();
    }

    @Override
    public void insertPreFolders(List<LimsSampleBean> sampleBeans) {
        if (CollectionUtils.isEmpty(sampleBeans)) return;
        List<Long> batchSampleIds = sampleBeans.stream().map(s -> s.getExt$Item("batchSampleId"))
                .map(Long::parseLong).distinct().collect(Collectors.toList());
        List<LimsBatchSampleProductBean> batchSampleProductBeans = sampleProductService.getDao()
                .selectListByOneColumnValues(batchSampleIds, "batchSampleId");

        List<Long> productIds = batchSampleProductBeans.stream().map(LimsBatchSampleProductBean::getProductId)
                .distinct().collect(Collectors.toList());
//        List<LimsProductBean> productBeans = productService.getDao()
//                .selectListByOneColumnValues(productIds, "productMainId");
        List<LimsProductBean> productBeans = productService.selectListByFilter(SearchFilter.instance().match("productMainId", productIds).filter(MatchPattern.OR));
        List<Long> etIds = productBeans.stream().map(LimsProductBean::getEtId).distinct().collect(Collectors.toList());
        List<LimsExperimentalTemplateBean> etBeans = limsExperimentalTemplateService.selectListByIds(etIds);

        List<LimsPreFolderBean> insertPreFolders = new ArrayList<>();
        List<Long> idList = ApplicationContextHelper.getNextIdentityList(batchSampleProductBeans.size());
        int index = 0;
        for (LimsBatchSampleProductBean batchSampleProductBean : batchSampleProductBeans) {
            LimsSampleBean sampleBean = sampleBeans.stream().filter(s -> s.getId()
                    .equals(batchSampleProductBean.getSampleId())).findFirst().get();
            LimsPreFolderBean folderBean = new LimsPreFolderBean();
            folderBean.setId(idList.get(index++));
            folderBean.setBatchId(batchSampleProductBean.getBatchId());
            folderBean.setBatchCode(batchSampleProductBean.getBatchCode());
            folderBean.setBatchSampleId(batchSampleProductBean.getBatchSampleId());
            folderBean.setSampleId(batchSampleProductBean.getSampleId());
            folderBean.setSampleCode(batchSampleProductBean.getSampleCode());
            folderBean.setSampleTypeCode(sampleBean.getSampleTypeCode());
            folderBean.setSampleTypeName(sampleBean.getSampleType());
            folderBean.setProductId(batchSampleProductBean.getProductId());
            folderBean.setProductCode(batchSampleProductBean.getProductCode());
            folderBean.setProductName(batchSampleProductBean.getProductName());
            Optional<LimsProductBean> first = productBeans.stream().filter(p -> p.getProductMainId().equals(batchSampleProductBean.getProductId())
                    && Arrays.asList(p.getSampleTypeCode().split(",")).contains(sampleBean.getSampleTypeCode())).findFirst();
            if (first.isPresent()) {
                LimsProductBean limsProductBean = first.get();
                folderBean.setProductEtId(limsProductBean.getId());
                folderBean.setEtId(limsProductBean.getEtId());
                folderBean.setEtCode(limsProductBean.getEtCode());
                folderBean.setEtName(limsProductBean.getExt$Item("ETNAME"));

//                folderBean.setJudgId(limsProductBean.getJudgId());
//                folderBean.setJudgCode(limsProductBean.getJudgCode());
                etBeans.stream().filter(et -> et.getId().equals(limsProductBean.getEtId())).findAny().ifPresent(et -> {
                    folderBean.setJudgId(et.getJudgId());
                    folderBean.setJudgCode(et.getJudgCode());
                });
            }
            insertPreFolders.add(folderBean);
        }
        getDao().fastInsert(insertPreFolders);

    }

    @Transactional
    @Override
    public void submit(RestJsonWrapperBean wrapperBean) {
        List<LimsPreFolderBean> preFolderBeans = wrapperBean.parse(LimsPreFolderBean.class);
        for (LimsPreFolderBean preFolderBean : preFolderBeans) {
            if (preFolderBean.getSampleCode() == null || preFolderBean.getEtId() == null) {
                return;
            }
        }
        List<LimsPreFolderBean> otherTasks = preFolderBeans.stream().filter(p -> !"M".equalsIgnoreCase(p.getType())).collect(Collectors.toList());
        if (otherTasks.isEmpty()) {
            return;
        }
        List<Long> etIds = otherTasks.stream().map(LimsPreFolderBean::getEtId).distinct().collect(Collectors.toList());
        List<LimsExperimentalTemplateTestBean> testBeans = etTestService.selectListByFilter(SearchFilter.instance()
                .match("etId", etIds).filter(MatchPattern.OR));
        if (testBeans.isEmpty()) {
            return;
        }

        Map<Long, List<LimsExperimentalTemplateTestBean>> spTestMap = testBeans.stream()
                .collect(Collectors.groupingBy(LimsExperimentalTemplateTestBean::getEtId));

//        List<LimsExperimentalTemplateTestMethodBean> spMethodBeans = spMethodService.selectListByFilter(SearchFilter.instance()
//                        .match("etTestId", testBeans.stream().map(LimsExperimentalTemplateTestBean::getId).collect(Collectors.toList())).filter(MatchPattern.OR),
//                Order.desc("defaultMethod"), Order.asc("methodCode"));
//        Map<Long, List<LimsExperimentalTemplateTestMethodBean>> spMethodMap = spMethodBeans.stream()
//                .collect(Collectors.groupingBy(LimsExperimentalTemplateTestMethodBean::getEtTestId));

        List<LimsFolderBean> folderBeans = new ArrayList<>();
        List<LimsOrderBean> orderBeans = new ArrayList<>();
        List<LimsPreOrderTaskBean> preOrderTaskBeans = new ArrayList<>();
        List<LimsOrderTaskBean> orderTaskBeans = new ArrayList<>();

        for (LimsPreFolderBean preFolderBean : otherTasks) {
            List<LimsExperimentalTemplateTestBean> spTests = spTestMap.get(preFolderBean.getEtId());
            if (ListUtils.isEmpty(spTests)) {
                continue;
            }
            LimsFolderBean folderBean = new LimsFolderBean();
            folderBean.setId(ApplicationContextHelper.getNextIdentity());
            folderBean.setBatchId(preFolderBean.getBatchId());
            folderBean.setBatchCode(preFolderBean.getBatchCode());
            folderBean.setPreFolderId(preFolderBean.getId());
            folderBean.setBatchSampleId(preFolderBean.getBatchSampleId());
            folderBean.setOriNo(preFolderBean.getSampleCode());
            folderBean.setProductId(preFolderBean.getProductId());
            folderBean.setProductCode(preFolderBean.getProductCode());
            folderBean.setProductName(preFolderBean.getProductName());
            folderBean.setEtId(preFolderBean.getEtId());
            folderBean.setEtCode(preFolderBean.getEtCode());
            folderBean.setEtName(preFolderBean.getEtName());
            folderBean.setExperimentNo(preFolderBean.getExperimentNo());
            folderBean.setJudgId(preFolderBean.getJudgId());
            folderBean.setJudgCode(preFolderBean.getJudgCode());
            folderBeans.add(folderBean);
            LimsOrderBean orderBean = new LimsOrderBean();
            orderBean.setId(ApplicationContextHelper.getNextIdentity());
            orderBean.setFolderId(folderBean.getId());
            orderBean.setSampleId(preFolderBean.getSampleId());
            orderBean.setSampleCode(preFolderBean.getSampleCode());
            orderBean.setSampleTypeCode(preFolderBean.getSampleTypeCode());
            orderBean.setSampleTypeName(preFolderBean.getSampleTypeName());
            orderBeans.add(orderBean);
            spTests.sort(Comparator.comparingLong(LimsExperimentalTemplateTestBean::getOrderNo));
            for (int i = 0; i < spTests.size(); i++) {
                LimsExperimentalTemplateTestBean spTest = spTests.get(i);
                LimsPreOrderTaskBean preOrderTaskBean = new LimsPreOrderTaskBean();
                preOrderTaskBean.setId(ApplicationContextHelper.getNextIdentity());
                preOrderTaskBean.setFolderId(folderBean.getId());
                preOrderTaskBean.setTestId(spTest.getTestId());
                preOrderTaskBean.setTestCode(spTest.getTestCode());
                preOrderTaskBean.setTestName(spTest.getTestName());
                preOrderTaskBean.setSort(spTest.getOrderNo());
                preOrderTaskBean.setEtTestId(spTest.getId());
                preOrderTaskBean.setLastEtTestIds(spTest.getLastTestIds());
                preOrderTaskBean.setStatus("draft");
                if (i == 0) {
                    LimsOrderTaskBean orderTaskBean = new LimsOrderTaskBean();
                    orderTaskBean.setId(ApplicationContextHelper.getNextIdentity());
                    orderTaskBean.setBatchId(preFolderBean.getBatchId());
                    orderTaskBean.setBatchCode(preFolderBean.getBatchCode());
                    orderTaskBean.setFolderId(folderBean.getId());
                    orderTaskBean.setOrderId(orderBean.getId());
                    orderTaskBean.setSampleId(preFolderBean.getSampleId());
                    orderTaskBean.setSampleCode(preFolderBean.getSampleCode());
                    orderTaskBean.setPreOrderTaskId(preOrderTaskBean.getId());
                    orderTaskBean.setTestId(spTest.getTestId());
                    orderTaskBean.setTestCode(spTest.getTestCode());
                    orderTaskBean.setTestName(spTest.getTestName());
                    orderTaskBean.setEtTestId(spTest.getId());
                    orderTaskBean.setSort(spTest.getOrderNo());
                    orderTaskBean.setParallelId(ApplicationContextHelper.getNextIdentity());
                    orderTaskBeans.add(orderTaskBean);

                    preOrderTaskBean.setOrderTaskId(orderTaskBean.getId());
                    preOrderTaskBean.setStatus("logged");
                }
                preOrderTaskBeans.add(preOrderTaskBean);
            }
            preFolderBean.setStatus("done");
        }
        folderService.getDao().insert(folderBeans);
        orderService.getDao().insert(orderBeans);
        preOrderTaskService.getDao().insert(preOrderTaskBeans);
        orderTaskService.getDao().insert(orderTaskBeans);
        getDao().fastUpdate(otherTasks, "status");

        List<Long> sampleIds = otherTasks.stream().map(LimsPreFolderBean::getSampleId).collect(Collectors.toList());
        auditRecordService.insertAuditRecords(sampleIds, "T_LIMS_SAMPLE", I18nHelper.getMessage("LIMS.MODULE.MENUS.TREE.PREFOLDER"), I18nHelper.getMessage("GIKAM.MODAL.SUBMIT"), null);

    }

    private void mixTaskSubmit(List<LimsPreFolderBean> mixTask, Map<Long, List<LimsPreTaskSupplementBean>> preTaskSupplementMaps, Map<Long, List<LimsTestSupplementBean>> testSupplementMaps,
                               List<LimsOrderBean> lastOrderBeans, Map<Long, List<LimsExperimentalTemplateTestBean>> spTestMap,
                               List<LimsFolderBean> insertFolders, List<LimsOrderBean> orderBeans, List<LimsPreOrderTaskBean> preOrderTaskBeans,
                               List<LimsOrderTaskBean> orderTaskBeans, List<LimsOrderTaskSupplementBean> orderTaskSupplementBeans) {
        List<Long> derivativeIds = mixTask.stream().map(LimsPreFolderBean::getSampleId).collect(Collectors.toList());
        List<LimsSampleDerivativeBean> limsSampleDerivativeBeans = limsSampleDerivativeService.selectListByFilter(SearchFilter.instance()
                .match("derivativeId", derivativeIds).filter(MatchPattern.OR));

        List<Long> folderIds = limsSampleDerivativeBeans.stream().map(LimsSampleDerivativeBean::getFolderId)
                .distinct().collect(Collectors.toList());
        List<LimsFolderBean> oldFolderBeans = folderService.selectListByIds(folderIds);

        int qty = 0;
        for (LimsPreFolderBean preFolderBean : mixTask) {
            List<LimsSampleDerivativeBean> derivativeBeans = limsSampleDerivativeBeans.stream()
                    .filter(l -> l.getDerivativeId().equals(preFolderBean.getSampleId())).collect(Collectors.toList());

            List<LimsExperimentalTemplateTestBean> spTests = spTestMap.get(preFolderBean.getEtId());
            if (ListUtils.isEmpty(spTests)) {
                continue;
            }
            List<LimsFolderBean> folderBeans = oldFolderBeans.stream().filter(f -> derivativeBeans.stream()
                    .anyMatch(d -> d.getFolderId().equals(f.getId()))).collect(Collectors.toList());
            qty = qty + spTests.size() * folderBeans.size() + folderBeans.size() * 3;
        }
        List<Long> nextIdentityList = ApplicationContextHelper.getNextIdentityList(qty + mixTask.size()); // 所有的ID
        AtomicInteger index = new AtomicInteger(0);
        mixTask.parallelStream().forEach(preFolderBean -> {
            List<LimsSampleDerivativeBean> derivativeBeans = limsSampleDerivativeBeans.stream()
                    .filter(l -> l.getDerivativeId().equals(preFolderBean.getSampleId())).collect(Collectors.toList());

            List<LimsExperimentalTemplateTestBean> spTests = spTestMap.get(preFolderBean.getEtId());
            if (ListUtils.isEmpty(spTests)) {
                return;
            }
            List<LimsFolderBean> folderBeans = oldFolderBeans.stream().filter(f -> derivativeBeans.stream()
                    .anyMatch(d -> d.getFolderId().equals(f.getId()))).collect(Collectors.toList());
            boolean first = true;
            Long parallelId = nextIdentityList.get(index.getAndIncrement());
            for (LimsFolderBean bean : folderBeans) {
                LimsFolderBean folderBean = new LimsFolderBean();
                BeanUtils.copyProperties(bean, folderBean, "id", "createdById", "createdTime", "createdByName", "createdByOrgId", "createdByOrgName"
                        , "status");
                folderBean.setId(nextIdentityList.get(index.getAndIncrement()));
                folderBean.setPreFolderId(preFolderBean.getId());
                insertFolders.add(folderBean);
                LimsOrderBean orderBean = new LimsOrderBean();
                orderBean.setId(nextIdentityList.get(index.getAndIncrement()));
                orderBean.setFolderId(folderBean.getId());
                orderBean.setSampleId(preFolderBean.getSampleId());
                orderBean.setSampleCode(preFolderBean.getSampleCode());
                orderBean.setSampleTypeName(preFolderBean.getSampleTypeName());
                orderBean.setSampleTypeCode(preFolderBean.getSampleTypeCode());
                orderBean.setOrderType("M");
                orderBeans.add(orderBean);
                spTests.sort(Comparator.comparingLong(LimsExperimentalTemplateTestBean::getOrderNo));
                for (int i = 0; i < spTests.size(); i++) {
                    LimsExperimentalTemplateTestBean spTest = spTests.get(i);
                    LimsPreOrderTaskBean preOrderTaskBean = new LimsPreOrderTaskBean();
                    preOrderTaskBean.setId(nextIdentityList.get(index.getAndIncrement()));
                    preOrderTaskBean.setFolderId(folderBean.getId());
                    preOrderTaskBean.setTestId(spTest.getTestId());
                    preOrderTaskBean.setTestCode(spTest.getTestCode());
                    preOrderTaskBean.setTestName(spTest.getTestName());
                    preOrderTaskBean.setSort(spTest.getOrderNo());
                    preOrderTaskBean.setEtTestId(spTest.getId());
                    preOrderTaskBean.setLastEtTestIds(spTest.getLastTestIds());
                    preOrderTaskBean.setStatus("draft");
                    if (i == 0) {
                        LimsOrderTaskBean orderTaskBean = new LimsOrderTaskBean();
                        orderTaskBean.setId(nextIdentityList.get(index.getAndIncrement()));
                        orderTaskBean.setBatchId(folderBean.getBatchId());
                        orderTaskBean.setBatchCode(folderBean.getBatchCode());
                        orderTaskBean.setFolderId(folderBean.getId());
                        orderTaskBean.setOrderId(orderBean.getId());
                        orderTaskBean.setSampleId(preFolderBean.getSampleId());
                        orderTaskBean.setSampleCode(preFolderBean.getSampleCode());
                        orderTaskBean.setPreOrderTaskId(preOrderTaskBean.getId());
                        orderTaskBean.setTestId(spTest.getTestId());
                        orderTaskBean.setTestCode(spTest.getTestCode());
                        orderTaskBean.setTestName(spTest.getTestName());
                        orderTaskBean.setEtTestId(spTest.getId());
                        orderTaskBean.setSort(spTest.getOrderNo());
                        orderTaskBean.setParallelId(parallelId);
                        if (!first) { // 除了第一道工序，其他都隐藏
                            orderTaskBean.setFlag(Constant.NO);
                        }
                        first = false;
                        // 历史任务下发 保存上到工序任务
                        if (!CollectionUtils.isEmpty(lastOrderBeans)) {
                            Optional<LimsOrderBean> orderOptional = lastOrderBeans.stream().filter(o -> o.getSampleId().equals(preFolderBean.getSampleId())).findFirst();
                            orderOptional.ifPresent(t -> {
                                if (!StringUtils.isBlank(t.getExt$Item("taskId"))) {
                                    try {
                                        orderTaskBean.setLastOrderTaskId(Long.parseLong(t.getExt$Item("taskId")));
                                    } catch (Exception e) {

                                    }
                                }
                            });
//                            orderOptional.ifPresent(t -> orderTaskBean.setLastOrderTaskId(Long.parseLong(t.getExt$Item("taskId"))));
                        }
                        orderTaskBeans.add(orderTaskBean);

                        preOrderTaskBean.setOrderTaskId(orderTaskBean.getId());
                        preOrderTaskBean.setStatus("logged");

                        // 获取工序补充信息
                        List<LimsTestSupplementBean> testSupplements = testSupplementMaps.get(orderTaskBean.getTestId());
                        if (!CollectionUtils.isEmpty(testSupplements)) {
                            Map<String, List<LimsTestSupplementBean>> collect = testSupplements.stream()
                                    .sorted(Comparator.comparingLong(LimsTestSupplementBean::getOrderNo))
                                    .collect(Collectors.groupingBy(LimsTestSupplementBean::getInformation));

                            List<LimsPreTaskSupplementBean> preTaskSupplements = preTaskSupplementMaps.get(preFolderBean.getId());
                            for (String s : collect.keySet()) {
                                LimsTestSupplementBean supplementBean = collect.get(s).get(0);
                                LimsOrderTaskSupplementBean orderTaskSupplementBean = new LimsOrderTaskSupplementBean();
//                                orderTaskSupplementBean.setId(ApplicationContextHelper.getNextIdentity());
                                orderTaskSupplementBean.setOperationBatch(preFolderBean.getOperationBatch());
                                orderTaskSupplementBean.setPreFolderId(preFolderBean.getId());
                                orderTaskSupplementBean.setOrderTaskId(orderTaskBean.getId());
                                orderTaskSupplementBean.setFieldName(supplementBean.getInformation());
                                orderTaskSupplementBean.setFieldValue(supplementBean.getDefaultValue());
                                orderTaskSupplementBean.setRequiredFlag(supplementBean.getRequiredFlag());
                                orderTaskSupplementBean.setOrderNo(supplementBean.getOrderNo());
                                orderTaskSupplementBean.setUnit(supplementBean.getUnit());
                                // 从批次补充信息带入
                                preTaskSupplements.stream().filter(p -> StringUtils.equals(p.getFieldName(), orderTaskSupplementBean.getFieldName()))
                                        .forEach(p -> orderTaskSupplementBean.setFieldValue(p.getFieldValue()));
                                orderTaskSupplementBeans.add(orderTaskSupplementBean);
                            }
                        }
                    }
                    preOrderTaskBeans.add(preOrderTaskBean);
                }
            }
            preFolderBean.setStatus("done");
        });
    }

    @Transactional
    @Override
    public void issueOfHistoricalTasks(RestJsonWrapperBean wrapperBean) {
        List<LimsPreFolderBean> parse = wrapperBean.parse(LimsPreFolderBean.class);
        if (CollectionUtils.isEmpty(parse)) {
            return;
        }
        List<LimsPreFolderBean> inserts = new ArrayList<>();
        List<LimsSampleBean> sampleBeans = new ArrayList<>();
        parse.forEach(limsPreFolderBean -> {
            LimsPreFolderBean folderBean = new LimsPreFolderBean();
            BeanUtils.copyProperties(limsPreFolderBean, folderBean, "id", "createdById", "createdTime", "createdByName", "createdByOrgId", "createdByOrgName"
                    , "experimentNo", "operationBatch", "remark", "addInBatch", "etId", "etCode", "etName");
            folderBean.setId(ApplicationContextHelper.getNextIdentity());
            folderBean.setType("H");
            folderBean.setStatus("draft");
            inserts.add(folderBean);
            LimsSampleBean sampleBean = new LimsSampleBean();
            sampleBean.setId(limsPreFolderBean.getSampleId());
            sampleBean.setStatus("inExperiment");
            sampleBeans.add(sampleBean);
        });
        getDao().insert(inserts);
        //修改样本状态为实验中
        limsSampleService.getDao().fastUpdate(sampleBeans, "status");
    }

    @Override
    public void issueOfMixTask(RestJsonWrapperBean wrapperBean) {
        List<LimsSampleDerivativeBean> parse = wrapperBean.parse(LimsSampleDerivativeBean.class);
        if (CollectionUtils.isEmpty(parse)) {
            return;
        }

        List<LimsPreFolderBean> inserts = new ArrayList<>();
        for (LimsSampleDerivativeBean bean : parse) {
            LimsPreFolderBean folderBean = new LimsPreFolderBean();
            folderBean.setId(ApplicationContextHelper.getNextIdentity());
            folderBean.setType("M");
            folderBean.setSampleId(bean.getDerivativeId());
            folderBean.setSampleCode(bean.getDerivativeNo());
            folderBean.setSampleTypeName(bean.getExt$Item("sampleType"));
            folderBean.setSampleTypeCode(bean.getExt$Item("sampleTypeCode"));
            inserts.add(folderBean);
        }
        getDao().insert(inserts);
    }

    @Override
    public Page<LimsPreFolderBean> selectIssueSamplePagination(RestJsonWrapperBean wrapper) {
        MapperParameter parameter = wrapper.extractMapFilter();
        PageRowBounds rowBounds = wrapper.extractPageRowBounds();
        Page<LimsPreFolderBean> page = this.selectPagination(() -> getDao().selectByCondition(parameter), rowBounds);
        if (page.getRows().isEmpty()) {
            return page;
        }
        List<LimsPreFolderBean> itemList = page.getRows();
        // 获取批次补充信息
        if (!itemList.isEmpty()) {
            List<LimsPreTaskSupplementBean> preTaskSupplementBeanList = preTaskSupplementService.selectListByFilter(SearchFilter.instance()
                    .match("preFolderId", itemList.stream().map(LimsPreFolderBean::getId).collect(Collectors.toList())).filter(MatchPattern.OR));
            itemList.forEach(preFolder -> {
                List<LimsPreTaskSupplementBean> preTaskSupplementList = preTaskSupplementBeanList.stream().filter(e -> e.getPreFolderId().equals(preFolder.getId())).collect(Collectors.toList());
                if (!preTaskSupplementList.isEmpty()) {
                    Map<String, String> fieldInfo = new HashMap<>();
                    preTaskSupplementList.forEach(supplement -> {
                        preFolder.setExt$Item(supplement.getFieldName(), supplement.getFieldValue());
                        fieldInfo.put(supplement.getFieldName(), supplement.getFieldValue());
                    });
                    preFolder.setExt$Item("supplementinfo", JSONObject.toJSONString(fieldInfo, SerializerFeature.WriteMapNullValue));
                }
            });
        }
        return new Pagination<>(page, itemList);
    }

    @Override
    @Transactional
    public void addOperationBatchTasks(RestJsonWrapperBean wrapper) {
        List<LimsPreFolderBean> preFolderBeans = wrapper.parse(LimsPreFolderBean.class);
        if (preFolderBeans.isEmpty()) return;
        String operationBatch = wrapper.getParamValue("operationBatch");
        preFolderBeans.forEach(p -> {
            p.setOperationBatch(operationBatch);
            p.setAddInBatch("1");
        });

        // 获取运营补充信息
        List<LimsExperimentalTemplateTestBean> templateTestBeans = etTestService.getDao().selectListByOneColumnValue(preFolderBeans.get(0).getEtId(), "etId", ArrayUtils.asList("testId"));
        List<Long> testIds = templateTestBeans.stream().map(LimsExperimentalTemplateTestBean::getTestId).distinct().collect(Collectors.toList());
        List<LimsTestSupplementBean> testSupplementBeans = testSupplementService.getDao().selectListByOneColumnValues(testIds, "testId");
        Map<String, List<LimsTestSupplementBean>> testSupplementMaps = testSupplementBeans.stream()
                .sorted(Comparator.comparingLong(LimsTestSupplementBean::getOrderNo))
                .collect(Collectors.groupingBy(LimsTestSupplementBean::getInformation));

        List<LimsPreTaskSupplementBean> preTaskSupplementBeans = new ArrayList<>();
        for (String s : testSupplementMaps.keySet()) {
            LimsTestSupplementBean bean = testSupplementMaps.get(s).get(0);
            for (LimsPreFolderBean preFolderBean : preFolderBeans) {
                LimsPreTaskSupplementBean preTaskSupplementBean = new LimsPreTaskSupplementBean();
                preTaskSupplementBean.setId(ApplicationContextHelper.getNextIdentity());
                preTaskSupplementBean.setOperationBatch(preFolderBean.getOperationBatch());
                preTaskSupplementBean.setPreFolderId(preFolderBean.getId());
                preTaskSupplementBean.setFieldName(bean.getInformation());
                preTaskSupplementBean.setFieldValue(bean.getDefaultValue());
                preTaskSupplementBean.setRequiredFlag(bean.getRequiredFlag());
                preTaskSupplementBean.setOrderNo(bean.getOrderNo());
                preTaskSupplementBean.setUnit(bean.getUnit());
                preTaskSupplementBeans.add(preTaskSupplementBean);
            }
        }

        getDao().fastUpdate(preFolderBeans, "operationBatch", "addInBatch");
        preTaskSupplementService.getDao().insert(preTaskSupplementBeans);
    }

    @Override
    @Transactional
    public void removeOperationBatchTasks(RestJsonWrapperBean wrapper) {
        List<LimsPreFolderBean> preFolderBeans = wrapper.parse(LimsPreFolderBean.class);
        if (preFolderBeans.isEmpty()) return;
        preFolderBeans.forEach(p -> {
            p.setOperationBatch(null);
            p.setAddInBatch("0");
        });

        List<Long> preFolderIds = preFolderBeans.stream().map(LimsPreFolderBean::getId).collect(Collectors.toList());
        List<LimsPreTaskSupplementBean> preTaskSupplementBeans = preTaskSupplementService.getDao().selectListByOneColumnValues(preFolderIds, "preFolderId", ArrayUtils.asList("id"));

        getDao().fastUpdate(preFolderBeans, "operationBatch", "addInBatch");
        preTaskSupplementService.getDao().deleteBy(preTaskSupplementBeans);
    }

    @Override
    @Transactional
    public void submitOperationBatch(RestJsonWrapperBean wrapper) {
        List<LimsOperationBatchBean> operationBatchBeans = wrapper.parse(LimsOperationBatchBean.class);

        if (operationBatchBeans.isEmpty()) return;
        operationBatchBeans.forEach(r -> {
            GikamConcurrentLocker.block(r.getId().toString());
        });

        List<String> operationBatchs = operationBatchBeans.stream().map(LimsOperationBatchBean::getOperationBatch).collect(Collectors.toList());
        List<LimsPreFolderBean> preFolderBeans = selectListByFilter(SearchFilter.instance()
                .match("operationBatch", operationBatchs).filter(MatchPattern.OR)
                .match("status", "draft").filter(MatchPattern.EQ));
        if (preFolderBeans.isEmpty()) {
            return;
        }

        for (LimsPreFolderBean preFolderBean : preFolderBeans) {
            if (preFolderBean.getSampleCode() == null || preFolderBean.getEtId() == null) {
                return;
            }
        }
        List<Long> etIds = preFolderBeans.stream().map(LimsPreFolderBean::getEtId).distinct().collect(Collectors.toList());
        List<LimsExperimentalTemplateTestBean> testBeans = etTestService.selectListByFilter(SearchFilter.instance()
                .match("etId", etIds).filter(MatchPattern.OR));
        if (testBeans.isEmpty()) {
            return;
        }

        Map<Long, List<LimsExperimentalTemplateTestBean>> spTestMap = testBeans.stream()
                .collect(Collectors.groupingBy(LimsExperimentalTemplateTestBean::getEtId));

        // 获取批次补充信息
        List<Long> preFolderIds = preFolderBeans.stream().map(LimsPreFolderBean::getId).collect(Collectors.toList());
        List<LimsPreTaskSupplementBean> preTaskSupplementBeans = preTaskSupplementService.getDao().selectListByOneColumnValues(preFolderIds, "preFolderId");
        Map<Long, List<LimsPreTaskSupplementBean>> preTaskSupplementMaps = preTaskSupplementBeans.stream().collect(Collectors.groupingBy(LimsPreTaskSupplementBean::getPreFolderId));
        // 获取工序补充信息
        List<Long> testIds = testBeans.stream().map(LimsExperimentalTemplateTestBean::getTestId).distinct().collect(Collectors.toList());
        List<LimsTestSupplementBean> testSupplementBeans = testSupplementService.getDao().selectListByOneColumnValues(testIds, "testId");
        Map<Long, List<LimsTestSupplementBean>> testSupplementMaps = testSupplementBeans.stream().collect(Collectors.groupingBy(LimsTestSupplementBean::getTestId));
        // 上一道工序
/*
        String ids = preFolderBeans.stream().map(t -> t.getSampleId().toString()).distinct().collect(Collectors.joining(","));
        MapperParameter mapperParameter = new MapperParameter();
        mapperParameter.put("sampleIds", ids);
        List<LimsOrderBean> lastOrderBeans = orderService.selectLastTaskBySampleId(mapperParameter);
*/
        // 历史下发上一道工序
        List<Long> hmSampleIds = preFolderBeans.stream().filter(p -> "H".equalsIgnoreCase(p.getType()) || "M".equalsIgnoreCase(p.getType()))
                .map(LimsPreFolderBean::getSampleId).distinct().collect(Collectors.toList());
        List<LimsOrderBean> lastOrderBeans = new ArrayList<>();
        if (!CollectionUtils.isEmpty(hmSampleIds)) {
            MapperParameter mapperParameter = new MapperParameter();
            mapperParameter.put("sampleIds", StringUtils.join(hmSampleIds, ","));
            lastOrderBeans = orderService.selectLastTaskBySampleId(mapperParameter);
        }

        List<LimsFolderBean> folderBeans = new ArrayList<>();
        List<LimsOrderBean> orderBeans = new ArrayList<>();
        List<LimsPreOrderTaskBean> preOrderTaskBeans = new ArrayList<>();
        List<LimsOrderTaskBean> orderTaskBeans = new ArrayList<>();
        List<LimsOrderTaskSupplementBean> orderTaskSupplementBeans = new ArrayList<>();

        List<LimsPreFolderBean> mixTask = preFolderBeans.stream().filter(p -> "M".equalsIgnoreCase(p.getType())).collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(mixTask)) {
            mixTaskSubmit(mixTask, preTaskSupplementMaps, testSupplementMaps, lastOrderBeans, spTestMap, folderBeans, orderBeans, preOrderTaskBeans, orderTaskBeans, orderTaskSupplementBeans);
        }
        List<LimsPreFolderBean> otherTasks = preFolderBeans.stream().filter(p -> !"M".equalsIgnoreCase(p.getType())).collect(Collectors.toList());
        int qty = 0; // preOrderTask 数量
        for (LimsPreFolderBean preFolderBean : otherTasks) {
            List<LimsExperimentalTemplateTestBean> spTests = spTestMap.get(preFolderBean.getEtId());
            qty = qty + spTests.size();
        }
        List<Long> nextIdentityList = ApplicationContextHelper.getNextIdentityList(otherTasks.size() * 4 + qty); // 所有的ID
        int index = 0;
        if (!otherTasks.isEmpty()) {
            for (LimsPreFolderBean preFolderBean : otherTasks) {
                List<LimsExperimentalTemplateTestBean> spTests = spTestMap.get(preFolderBean.getEtId());
                if (ListUtils.isEmpty(spTests)) {
                    continue;
                }
                LimsFolderBean folderBean = new LimsFolderBean();
                folderBean.setId(nextIdentityList.get(index++));
                folderBean.setBatchId(preFolderBean.getBatchId());
                folderBean.setBatchCode(preFolderBean.getBatchCode());
                folderBean.setOperationBatch(preFolderBean.getOperationBatch());
                folderBean.setPreFolderId(preFolderBean.getId());
                folderBean.setBatchSampleId(preFolderBean.getBatchSampleId());
                folderBean.setOriNo(preFolderBean.getSampleCode());
                folderBean.setProductId(preFolderBean.getProductId());
                folderBean.setProductCode(preFolderBean.getProductCode());
                folderBean.setProductName(preFolderBean.getProductName());
                folderBean.setEtId(preFolderBean.getEtId());
                folderBean.setEtCode(preFolderBean.getEtCode());
                folderBean.setEtName(preFolderBean.getEtName());
                folderBean.setExperimentNo(preFolderBean.getExperimentNo());
                folderBean.setJudgId(preFolderBean.getJudgId());
                folderBean.setJudgCode(preFolderBean.getJudgCode());
                folderBeans.add(folderBean);
                LimsOrderBean orderBean = new LimsOrderBean();
                orderBean.setId(nextIdentityList.get(index++));
                orderBean.setFolderId(folderBean.getId());
                orderBean.setSampleId(preFolderBean.getSampleId());
                orderBean.setSampleCode(preFolderBean.getSampleCode());
                orderBean.setSampleTypeCode(preFolderBean.getSampleTypeCode());
                orderBean.setSampleTypeName(preFolderBean.getSampleTypeName());
                orderBeans.add(orderBean);
                spTests.sort(Comparator.comparingLong(LimsExperimentalTemplateTestBean::getOrderNo));
                for (int i = 0; i < spTests.size(); i++) {
                    LimsExperimentalTemplateTestBean spTest = spTests.get(i);
                    LimsPreOrderTaskBean preOrderTaskBean = new LimsPreOrderTaskBean();
                    preOrderTaskBean.setId(nextIdentityList.get(index++));
                    preOrderTaskBean.setFolderId(folderBean.getId());
                    preOrderTaskBean.setTestId(spTest.getTestId());
                    preOrderTaskBean.setTestCode(spTest.getTestCode());
                    preOrderTaskBean.setTestName(spTest.getTestName());
                    preOrderTaskBean.setSort(spTest.getOrderNo());
                    preOrderTaskBean.setEtTestId(spTest.getId());
                    preOrderTaskBean.setLastEtTestIds(spTest.getLastTestIds());
                    preOrderTaskBean.setStatus("draft");
                    if (i == 0) {
                        LimsOrderTaskBean orderTaskBean = new LimsOrderTaskBean();
                        orderTaskBean.setId(nextIdentityList.get(index++));
                        orderTaskBean.setBatchId(preFolderBean.getBatchId());
                        orderTaskBean.setBatchCode(preFolderBean.getBatchCode());
                        orderTaskBean.setFolderId(folderBean.getId());
                        orderTaskBean.setOrderId(orderBean.getId());
                        orderTaskBean.setSampleId(preFolderBean.getSampleId());
                        orderTaskBean.setSampleCode(preFolderBean.getSampleCode());
                        orderTaskBean.setPreOrderTaskId(preOrderTaskBean.getId());
                        orderTaskBean.setTestId(spTest.getTestId());
                        orderTaskBean.setTestCode(spTest.getTestCode());
                        orderTaskBean.setTestName(spTest.getTestName());
                        orderTaskBean.setEtTestId(spTest.getId());
                        orderTaskBean.setSort(spTest.getOrderNo());
                        orderTaskBean.setParallelId(nextIdentityList.get(index++));
/*                        // 历史任务下发 保存上到工序任务
                        if (!CollectionUtils.isEmpty(lastOrderBeans)) {
                            Optional<LimsOrderBean> orderOptional = lastOrderBeans.stream().filter(o -> o.getSampleId().equals(preFolderBean.getSampleId())).findFirst();
                            orderOptional.ifPresent(t -> orderTaskBean.setLastOrderTaskId(Long.parseLong(t.getExt$Item("taskId"))));
                        }*/
                        // 历史任务下发 保存上到工序任务
                        if ("H".equalsIgnoreCase(preFolderBean.getType()) && !CollectionUtils.isEmpty(lastOrderBeans)) {
                            Optional<LimsOrderBean> orderOptional = lastOrderBeans.stream().filter(o -> o.getSampleId().equals(preFolderBean.getSampleId())).findFirst();
                            orderOptional.ifPresent(t -> {
                                if (!StringUtils.isBlank(t.getExt$Item("taskId"))) {
                                    try {
                                        orderTaskBean.setLastOrderTaskId(Long.parseLong(t.getExt$Item("taskId")));
                                    } catch (Exception e) {

                                    }
                                }
                            });
                        }
                        orderTaskBeans.add(orderTaskBean);

                        preOrderTaskBean.setOrderTaskId(orderTaskBean.getId());
                        preOrderTaskBean.setStatus("logged");

                        // 获取工序补充信息
                        List<LimsTestSupplementBean> testSupplements = testSupplementMaps.get(orderTaskBean.getTestId());
                        if (!testSupplementBeans.isEmpty()) {
                            if (testSupplements != null) {
                                Map<String, List<LimsTestSupplementBean>> collect = testSupplements.stream()
                                        .sorted(Comparator.comparingLong(LimsTestSupplementBean::getOrderNo))
                                        .collect(Collectors.groupingBy(LimsTestSupplementBean::getInformation));

                                List<LimsPreTaskSupplementBean> preTaskSupplements = preTaskSupplementMaps.get(preFolderBean.getId());
                                for (String s : collect.keySet()) {
                                    LimsTestSupplementBean bean = collect.get(s).get(0);
                                    LimsOrderTaskSupplementBean orderTaskSupplementBean = new LimsOrderTaskSupplementBean();
//                                    orderTaskSupplementBean.setId(ApplicationContextHelper.getNextIdentity());
                                    orderTaskSupplementBean.setOperationBatch(preFolderBean.getOperationBatch());
                                    orderTaskSupplementBean.setPreFolderId(preFolderBean.getId());
                                    orderTaskSupplementBean.setOrderTaskId(orderTaskBean.getId());
                                    orderTaskSupplementBean.setFieldName(bean.getInformation());
                                    orderTaskSupplementBean.setFieldValue(bean.getDefaultValue());
                                    orderTaskSupplementBean.setRequiredFlag(bean.getRequiredFlag());
                                    orderTaskSupplementBean.setOrderNo(bean.getOrderNo());
                                    orderTaskSupplementBean.setUnit(bean.getUnit());
                                    // 从批次补充信息带入
                                    preTaskSupplements.stream().filter(p -> StringUtils.equals(p.getFieldName(), orderTaskSupplementBean.getFieldName()))
                                            .forEach(p -> orderTaskSupplementBean.setFieldValue(p.getFieldValue()));
                                    orderTaskSupplementBeans.add(orderTaskSupplementBean);
                                }
                            }
                        }
                    }
                    preOrderTaskBeans.add(preOrderTaskBean);
                }
                preFolderBean.setStatus("done");
            }
        }
        folderService.getDao().fastInsert(folderBeans);
        orderService.getDao().fastInsert(orderBeans);
        preOrderTaskService.getDao().fastInsert(preOrderTaskBeans);
        orderTaskService.getDao().fastInsert(orderTaskBeans);
        List<Long> supplementIds = ApplicationContextHelper.getNextIdentityList(orderTaskSupplementBeans.size());
/*        int a = 0;
        for (LimsOrderTaskSupplementBean orderTaskSupplementBean : orderTaskSupplementBeans) {
            orderTaskSupplementBean.setId(supplementIds.get(a ++));
        }*/
        AtomicInteger a = new AtomicInteger(0);
        orderTaskSupplementBeans.forEach(o -> o.setId(supplementIds.get(a.getAndIncrement())));

        orderTaskSupplementService.getDao().fastInsert(orderTaskSupplementBeans);
        getDao().fastUpdate(preFolderBeans, "status");
        operationBatchBeans.forEach(b -> b.setStatus("done"));
        operationBatchService.getDao().fastUpdate(operationBatchBeans, "status");

        List<Long> sampleIds = otherTasks.stream().map(LimsPreFolderBean::getSampleId).collect(Collectors.toList());
        auditRecordService.insertAuditRecords(sampleIds, "T_LIMS_SAMPLE", I18nHelper.getMessage("LIMS.MODULE.MENUS.TREE.PREFOLDER"), I18nHelper.getMessage("GIKAM.MODAL.SUBMIT"), null);

        List<Long> folderIds = folderBeans.stream().map(LimsFolderBean::getId).collect(Collectors.toList());
//        limsBatchSampleProductService.setBatchProductStatus(folderIds);
        limsBatchSampleProductService.setBatchProductWithStatus(folderIds, "inExperiment");
    }

    @Override
    @Transactional
    public void splitSample(RestJsonWrapperBean wrapper) {
        List<LimsPreFolderBean> preFolderBeans = wrapper.parse(LimsPreFolderBean.class);
        if (preFolderBeans.isEmpty()) {
            throw new InvalidDataException("参数为空！");
        }
        String splitFlag = wrapper.getParamValue("splitFlag");
        int splitNum = NumberUtils.parseInt(wrapper.getParamValue("splitNum"));
        List<Long> sampleIds = preFolderBeans.stream().map(LimsPreFolderBean::getSampleId).collect(Collectors.toList());
        List<String> sampleCodes = preFolderBeans.stream().map(LimsPreFolderBean::getSampleCode).collect(Collectors.toList());
        List<LimsSampleBean> sampleBeans = sampleService.getDao().selectListByIds(sampleIds);
        Map<Long, List<LimsSampleBean>> oriSampleMap = sampleBeans.stream().collect(Collectors.groupingBy(LimsSampleBean::getId));
        List<LimsSampleBean> sampleBeanList = sampleService.getDao().selectListByOneColumnValues(sampleCodes, "oriNo");
        List<LimsSampleBean> insertSampleBeans = new ArrayList<>();
        List<LimsPreFolderBean> insertPreFolderBeans = new ArrayList<>();
        Map<String, List<LimsSampleBean>> sampleMap = sampleBeanList.stream().collect(Collectors.groupingBy(LimsSampleBean::getOriNo));
        List<Long> idList = ApplicationContextHelper.getNextIdentityList(2 * splitNum * preFolderBeans.size());
        for (LimsPreFolderBean preFolderBean : preFolderBeans) {
            if (!"1".equals(splitFlag)) preFolderBean.setStatus("done");
            Long sampleId = preFolderBean.getSampleId();
            if (oriSampleMap.containsKey(sampleId)) {
                LimsSampleBean sourceSample = oriSampleMap.get(sampleId).get(0);
                String oriNo = sourceSample.getOriNo();
                List<String> sampleCodeList = new ArrayList<>();
                if (sampleMap.containsKey(oriNo)) {
                    List<LimsSampleBean> oriNoSamples = sampleMap.get(oriNo);
                    sampleCodeList = oriNoSamples.stream().map(LimsSampleBean::getSampleCode).collect(Collectors.toList());
                }
                int j = 1;
                for (int i = 0; i < splitNum; i++) {
                    LimsSampleBean targetSample = new LimsSampleBean();
                    BeanUtils.copyProperties(sourceSample, targetSample, "id", "createdById", "createdTime", "createdByName", "createdByOrgId",
                            "createdByOrgName", "boardId", "boardHoleId", "locations", "useFlg", "qcSampleFlg");
                    String sampleCode = preFolderBean.getSampleCode() + "-" + j;
                    while (true) {
                        if (sampleCodeList.contains(sampleCode)) {
                            j++;
                            sampleCode = preFolderBean.getSampleCode() + "-" + j;
                        } else {
                            break;
                        }
                    }
                    j++;
                    targetSample.setId(idList.remove(0));
                    targetSample.setParentNo(preFolderBean.getSampleCode());
                    if (sourceSample.getOriginalFlg().equals(Constant.YES)) {
                        targetSample.setOriNo(sourceSample.getSampleCode());
                    } else {
                        targetSample.setOriNo(sourceSample.getOriNo());
                    }
                    targetSample.setOriginalFlg(Constant.NO);
                    targetSample.setSampleCode(sampleCode);
                    insertSampleBeans.add(targetSample);

                    LimsPreFolderBean targetFolder = new LimsPreFolderBean();
                    BeanUtils.copyProperties(preFolderBean, targetFolder, "id", "status", "createdById", "createdTime", "createdByName", "createdByOrgId", "createdByOrgName");
                    targetFolder.setType("S");//分样样本
                    targetFolder.setSampleCode(targetSample.getSampleCode());
                    targetFolder.setSampleId(targetSample.getId());
                    targetFolder.setId(idList.remove(0));
                    insertPreFolderBeans.add(targetFolder);
                }
            }
        }
        if (!"1".equals(splitFlag)) {
            getDao().fastUpdate(preFolderBeans, "status");
        }
        getDao().fastInsert(insertPreFolderBeans);
        sampleService.getDao().fastInsert(insertSampleBeans);
    }

    @Override//任务下发分样生成样本或衍生物
    @Transactional
    public void separateSample(RestJsonWrapperBean wrapper) {
        List<LimsPreFolderBean> preFolderBeans = wrapper.parse(LimsPreFolderBean.class);
        if (preFolderBeans.isEmpty()) return;
        int separateSampleNum = Integer.parseInt(preFolderBeans.get(0).getExt$Item("separateSampleNum"));//分样数量
        //查询样本和衍生物
        List<Long> sampleIds = preFolderBeans.stream().map(LimsPreFolderBean::getSampleId).collect(Collectors.toList());
        List<String> sampleCodes = preFolderBeans.stream().map(LimsPreFolderBean::getSampleCode).distinct().collect(Collectors.toList());

        List<LimsSampleBean> sampleBeans = sampleService.selectListByFilter(SearchFilter.instance()
                .match("id", sampleIds).filter(MatchPattern.OR));
        List<LimsBatchSampleProductBean> productBeans = limsBatchSampleProductService.selectListByFilter(SearchFilter.instance()
                .match("sampleId", sampleIds).filter(MatchPattern.OR));

        List<LimsSampleBean> sampleBeans2 = sampleService.selectListByFilter(SearchFilter.instance()
                .match("sampleCode", sampleCodes).filter(MatchPattern.CISB));
        List<LimsSampleDerivativeBean> sampleDerivativeBeans = limsSampleDerivativeService.selectListByFilter(SearchFilter.instance()
                .match("id", sampleIds).filter(MatchPattern.OR));
        List<LimsSampleDerivativeBean> sampleDerivativeBeans2 = limsSampleDerivativeService.selectListByFilter(SearchFilter.instance()
                .match("derivativeNo", sampleCodes).filter(MatchPattern.OR));
        List<LimsSampleBean> sampleBeanList = new ArrayList<>();
        List<LimsSampleDerivativeBean> sampleDerivativeBeanList = new ArrayList<>();
        List<LimsPreFolderBean> preFolderBeanList = new ArrayList<>();
        List<LimsBatchSampleProductBean> productBeanList = new ArrayList<>();
        preFolderBeans.stream().forEach(p -> {
            //判断任务下发选择的是否有相同样本编号的
            List<LimsPreFolderBean> preFolders = preFolderBeans.stream().filter(f -> p.getSampleId().equals(f.getSampleId())).collect(Collectors.toList());
            //样本
            List<LimsSampleBean> samples = sampleBeans.stream().filter(s -> s.getId().equals(p.getSampleId())).collect(Collectors.toList());
            //筛选样本编号相似的
            List<LimsSampleBean> samples2 = sampleBeans2.stream().filter(s -> s.getSampleCode().contains(p.getSampleCode())).collect(Collectors.toList());
            samples2.addAll(sampleBeanList.stream().filter(s -> s.getSampleCode().contains(p.getSampleCode())).collect(Collectors.toList()));
            //衍生物
            List<LimsSampleDerivativeBean> sampleDerivatives = sampleDerivativeBeans.stream().filter(s -> s.getId().equals(p.getSampleId())).collect(Collectors.toList());
            List<LimsSampleDerivativeBean> sampleDerivative2 = sampleDerivativeBeans2.stream().filter(s -> s.getDerivativeNo().contains(p.getSampleCode())).collect(Collectors.toList());
            sampleDerivative2.addAll(sampleDerivativeBeanList.stream().filter(s -> s.getDerivativeNo().contains(p.getSampleCode())).collect(Collectors.toList()));

            if (!samples.isEmpty()) {
                LimsSampleBean sampleBean = samples.get(0);
                for (int i = 0; i < separateSampleNum; i++) {
                    LimsSampleBean sample = new LimsSampleBean();
                    BeanUtils.copyProperties(sampleBean, sample, "id", "createdById", "createdTime", "createdByName", "createdByOrgId",
                            "createdByOrgName", "boardId", "boardHoleId", "locations", "useFlg", "qcSampleFlg");
                    sample.setId(ApplicationContextHelper.getNextIdentity());
                    //原样编号+序号
                    sample.setSampleCode(sampleBean.getOriNo() + "-" + (i + samples2.size()));
                    sample.setParentNo(sampleBean.getSampleCode());
                    if (sample.getOriginalFlg().equals(Constant.YES)) {
                        sample.setOriNo(sampleBean.getSampleCode());
                    } else {
                        sample.setOriNo(sampleBean.getOriNo());
                    }
                    sample.setOriginalFlg(Constant.NO);

                    //添加任务单
                    LimsPreFolderBean preFolderBean = new LimsPreFolderBean();
                    BeanUtils.copyProperties(p, preFolderBean, "id", "createdById", "createdTime", "createdByName", "createdByOrgId", "createdByOrgName");

                    //分样标志用于区分和删除
                    preFolderBean.setType("S");//分样样本
                    preFolderBean.setSampleCode(sample.getSampleCode());
                    preFolderBean.setSampleId(sample.getId());
                    sampleBeanList.add(sample);
                    preFolderBean.setId(ApplicationContextHelper.getNextIdentity());
                    preFolderBeanList.add(preFolderBean);
                    /*LimsBatchSampleBean batchSampleBean=new LimsBatchSampleBean();
                    batchSampleBean.setId(ApplicationContextHelper.getNextIdentity());
                    batchSampleBean.setBatchId();
                    batchSampleBean.setBatchCode();
                    batchSampleBean.setSampleCode();
                    batchSampleBean.setSampleId();
                    LimsBatchSampleProductBean productBean=new LimsBatchSampleProductBean();
                    productBean.setId(ApplicationContextHelper.getNextIdentity());
                    productBean.setBatchCode();
                    productBean.setBatchId();
                    productBean.setBatchSampleId();
                    productBean.setProductName();
                    productBean.setProductId();
                    productBean.setProductCode();*/
                }
            }
            if (!sampleDerivatives.isEmpty()) {
                LimsSampleDerivativeBean sampleBean = sampleDerivatives.get(0);
                for (int i = 0; i < separateSampleNum; i++) {
                    LimsSampleDerivativeBean derivative = new LimsSampleDerivativeBean();
                    BeanUtils.copyProperties(sampleBean, derivative, "id", "createdById", "createdTime", "createdByName", "createdByOrgId", "createdByOrgName");
                    derivative.setId(ApplicationContextHelper.getNextIdentity());
                    //原样编号+序号
                    derivative.setDerivativeNo(sampleBean.getDerivativeNo() + "-" + (i + samples2.size()));

                    //添加任务单
                    LimsPreFolderBean preFolderBean = new LimsPreFolderBean();
                    BeanUtils.copyProperties(p, preFolderBean, "id", "createdById", "createdTime", "createdByName", "createdByOrgId", "createdByOrgName");

                    //分样标志用于区分和删除
                    preFolderBean.setType("S");//分样样本
                    preFolderBean.setSampleCode(derivative.getDerivativeNo());
                    preFolderBean.setSampleId(derivative.getId());
                    sampleDerivativeBeanList.add(derivative);
                    preFolderBean.setId(ApplicationContextHelper.getNextIdentity());
                    preFolderBeanList.add(preFolderBean);
                }
            }


            p.setStatus("done");//
        });

        if (!sampleBeanList.isEmpty()) {
            sampleService.getDao().insert(sampleBeanList);
        }
        if (!sampleDerivativeBeanList.isEmpty()) {
            limsSampleDerivativeService.getDao().insert(sampleDerivativeBeanList);
        }
        if (!preFolderBeanList.isEmpty()) {
            getDao().insert(preFolderBeanList);
        }
        getDao().update(preFolderBeans, "status");

    }

    @Transactional
    @Override
    public void stop(RestJsonWrapperBean wrapperBean) {
        List<LimsPreFolderBean> folderBeans = wrapperBean.parse(LimsPreFolderBean.class);
        List<LimsSampleBean> sampleBeans = new ArrayList<>();
        List<LimsBatchSampleProductBean> searchBy = new ArrayList<>();
        folderBeans.forEach(f -> {
            f.setStatus("stop");
            LimsSampleBean sampleBean = new LimsSampleBean();
            sampleBean.setId(f.getSampleId());
            sampleBean.setStatus("done");
            sampleBeans.add(sampleBean);

            LimsBatchSampleProductBean select = new LimsBatchSampleProductBean();
            select.setBatchSampleId(f.getBatchSampleId());
            select.setProductId(f.getProductId());
            searchBy.add(select);
        });
        List<LimsBatchSampleProductBean> productBeans = limsBatchSampleProductService.getDao().selectList(searchBy, Arrays.asList("batchSampleId", "productId"), Collections.singletonList("id"));
        productBeans.forEach(p -> p.setStatus("sampleStop"));// 送检单样本产品表改为样本终止 60255171
        limsBatchSampleProductService.getDao().update(productBeans, Collections.singletonList("status"));
        //修改样本状态为实验中
        limsSampleService.getDao().update(sampleBeans, "status");
        getDao().update(folderBeans, "status");
    }

    @Override
    public Page<LimsPreFolderBean> selectForHistory(RestJsonWrapperBean wrapper) {
        MapperParameter parameter = wrapper.extractMapFilter();
        PageRowBounds rowBounds = wrapper.extractPageRowBounds();
        return this.selectPagination(() -> getDao().selectForHistory(parameter), rowBounds);
    }

    @Override
    public void remove(RestJsonWrapperBean wrapperBean) {
        List<LimsPreFolderBean> folderBeans = wrapperBean.parse(LimsPreFolderBean.class);
//        List<LimsSampleBean> sampleBeans = new ArrayList<>();
//        List<LimsBatchSampleProductBean> searchBy = new ArrayList<>();
        folderBeans.forEach(f -> {
            f.setStatus("done");
//            LimsSampleBean sampleBean = new LimsSampleBean();
//            sampleBean.setId(f.getSampleId());
//            sampleBean.setStatus("done");
//            sampleBeans.add(sampleBean);
//
//            LimsBatchSampleProductBean select = new LimsBatchSampleProductBean();
//            select.setBatchSampleId(f.getBatchSampleId());
//            select.setProductId(f.getProductId());
//            searchBy.add(select);
        });
//        List<LimsBatchSampleProductBean> productBeans = limsBatchSampleProductService.getDao().selectList(searchBy, Arrays.asList("batchSampleId", "productId"), Collections.singletonList("id"));
//        productBeans.forEach(p -> p.setStatus("stop"));
//        limsBatchSampleProductService.getDao().update(productBeans, Collections.singletonList("status"));
//        //修改样本状态为实验中
//        limsSampleService.getDao().update(sampleBeans, "status");
        getDao().update(folderBeans, "status");
    }
}
